package q1.project.modules.system.tenant.entity;

import jakarta.persistence.*;
import java.time.LocalDateTime;
import lombok.Getter;
import lombok.Setter;
import q1.project.common.enums.IsolationModeEnum;
import q1.project.common.enums.TenantStatusEnum;
import q1.project.common.enums.TenantTypeEnum;
import q1.project.core.entity.BaseEntity;
import q1.project.core.jpa.annotation.Comment;

/**
 * 租户实体(优化版) 租户实体本身不需要客户过滤
 *
 * @author Q1 Team
 * @version 2.0
 */
@Getter
@Setter
@Entity
@Table(
    name = "q1_tenant",
    indexes = {
      @Index(name = "idx_tenant_code", columnList = "tenant_code"),
      @Index(name = "idx_status", columnList = "status"),
      @Index(name = "idx_admin_user_id", columnList = "admin_user_id")
    })
// 租户实体不应用客户过滤器(因为它本身就是租户表)
@org.hibernate.annotations.Filter(name = "tenantFilter", condition = "1=1")
public class TenantEntity extends BaseEntity {

  /** 租户标识(唯一) 用于 URL 子域名、API 请求头等 格式：小写字母+数字，如 tenant001 */
  @Comment("租户标识")
  @Column(name = "tenant_code", unique = true, nullable = false, length = 50)
  private String tenantCode;

  /** 租户名称 论坛名称 */
  @Comment("租户名称")
  @Column(name = "tenant_name", nullable = false, length = 100)
  private String tenantName;

  /** 租户类型 */
  @Comment("租户类型")
  @Enumerated(EnumType.STRING)
  @Column(name = "tenant_type", nullable = false, length = 20)
  private TenantTypeEnum tenantType = TenantTypeEnum.FREE;

  /** 隔离模式 */
  @Comment("隔离模式")
  @Enumerated(EnumType.STRING)
  @Column(name = "isolation_mode", nullable = false, length = 20)
  private IsolationModeEnum isolationMode = IsolationModeEnum.ID;

  /** 数据库名称(数据库隔离模式使用) */
  @Comment("数据库名称")
  @Column(name = "database_name", length = 100)
  private String databaseName;

  /** 租户状态 */
  @Comment("租户状态")
  @Enumerated(EnumType.STRING)
  @Column(nullable = false, length = 20)
  private TenantStatusEnum status = TenantStatusEnum.ACTIVE;

  /** 租户管理员用户ID */
  @Comment("租户管理员用户ID")
  @Column(name = "admin_user_id", nullable = false, length = 32)
  private String adminUserId;

  /** 到期时间 */
  @Comment("到期时间")
  @Column(name = "expire_time")
  private LocalDateTime expireTime;

  /** 最大用户数 null 表示无限制 */
  @Comment("最大用户数")
  @Column(name = "max_users")
  private Integer maxUsers;

  /** 最大存储空间(MB) null 表示无限制 */
  @Comment("最大存储空间(MB)")
  @Column(name = "max_storage")
  private Long maxStorage;

  /** 当前用户数 */
  @Comment("当前用户数")
  @Column(name = "current_users", nullable = false)
  private Integer currentUsers = 0;

  /** 当前存储使用量(MB) */
  @Comment("当前存储使用量(MB)")
  @Column(name = "current_storage", nullable = false)
  private Long currentStorage = 0L;

  /** 论坛 LOGO URL */
  @Comment("论坛LOGO URL")
  @Column(name = "logo_url", length = 500)
  private String logoUrl;

  /** 论坛描述 */
  @Comment("论坛描述")
  @Column(columnDefinition = "TEXT")
  private String description;

  /** 自定义域名 */
  @Comment("自定义域名")
  @Column(name = "custom_domain", length = 100)
  private String customDomain;

  /** 联系邮箱 */
  @Comment("联系邮箱")
  @Column(name = "contact_email", length = 100)
  private String contactEmail;

  /** 联系电话 */
  @Comment("联系电话")
  @Column(name = "contact_phone", length = 20)
  private String contactPhone;

  /** 检查是否可用 */
  public boolean isAvailable() {
    return status == TenantStatusEnum.ACTIVE
        && (expireTime == null || expireTime.isAfter(LocalDateTime.now()));
  }

  /** 检查是否达到用户数限制 */
  public boolean isUserLimitReached() {
    return maxUsers != null && currentUsers >= maxUsers;
  }

  /** 检查是否达到存储空间限制 */
  public boolean isStorageLimitReached() {
    return maxStorage != null && currentStorage >= maxStorage;
  }

  /** 覆盖父类方法，租户实体的 tenantId 就是自己的 ID */
  @Override
  @PrePersist
  protected void onCreate() {
    if (getId() == null || getId().isEmpty()) {
      setId(java.util.UUID.randomUUID().toString().replace("-", ""));
    }

    // 租户实体的 tenantId 就是自己的主键 ID
    // 使用内部方法设置，避免验证
    setTenantIdInternal(getId());

    if (getCreateTime() == null) {
      setCreateTime(LocalDateTime.now());
    }
    if (getUpdateTime() == null) {
      setUpdateTime(LocalDateTime.now());
    }
  }

  /** 覆盖父类方法，租户实体不需要自动设置租户ID */
  @Override
  protected void autoSetTenantId() {
    // 租户实体不需要从上下文获取租户ID
    // tenantId 会在 onCreate() 中设置为主键 ID
  }
}
